Debugging and Testing a Macro Model
Macro offers a range of utility functions designed to make debugging and testing new models and sectors more efficient and straightforward.
The following functions are organized with the following sections:
- Working with a System
- Generating a Model
- Working with Nodes
- Working with Assets
- Working with Edges
- Working with Transformations
- Working with Storages
- Time Management
- Results Collection
Working with a System
Let's start by loading a system from a case folder (you can find more information about the structure of this folder in the Running Macro section).
load_system
julia> using MacroEnergyjulia> system = MacroEnergy.load_system("doctest");[ Info: Loading system from doctest/system_data.json [ Info: Loading system data [ Info: Done loading system data. It took 0.77 seconds [ Info: Generating system ┌ Warning: Using default weights = 1 as no period map provided and each period maps to itself └ @ MacroEnergy ~/work/MacroEnergy.jl/MacroEnergy.jl/src/load_inputs/load_time_data.jl:198 ┌ Warning: Using default weights = 1 as no period map provided and each period maps to itself └ @ MacroEnergy ~/work/MacroEnergy.jl/MacroEnergy.jl/src/load_inputs/load_time_data.jl:198 ┌ Warning: Using default weights = 1 as no period map provided and each period maps to itself └ @ MacroEnergy ~/work/MacroEnergy.jl/MacroEnergy.jl/src/load_inputs/load_time_data.jl:198 ┌ Warning: Using default weights = 1 as no period map provided and each period maps to itself └ @ MacroEnergy ~/work/MacroEnergy.jl/MacroEnergy.jl/src/load_inputs/load_time_data.jl:198 ┌ Warning: Using default weights = 1 as no period map provided and each period maps to itself └ @ MacroEnergy ~/work/MacroEnergy.jl/MacroEnergy.jl/src/load_inputs/load_time_data.jl:198 ┌ Warning: Using default weights = 1 as no period map provided and each period maps to itself └ @ MacroEnergy ~/work/MacroEnergy.jl/MacroEnergy.jl/src/load_inputs/load_time_data.jl:198 [ Info: ++ Creating new location: NE ERROR: KeyError: key :commodity not found
propertynames
The propertynames function in Julia can be used to retrieve the names of the fields of a System object, such as the data directory path, settings, and locations.
julia> propertynames(system)ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
data_dirpath: Path to the data directory.settings: Settings of the system.commodities: Sectors modeled in the system.timedata: Time resolution for each sector.locations: Vector of allLocations andNodes.assets: Vector of allAssets.
A System consists of six primary fields, each of which can be accessed using dot notation:
julia> system.data_dirpathERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> system.settingsERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
When interacting with a System, users might need to retrieve information about specific nodes, locations, or assets. The functions listed below are helpful for these tasks:
find_node
Finds a node by its ID.
julia> co2_node = MacroEnergy.find_node(system.locations, :co2_sink);ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
get_asset_types
Retrieves all the types of assets in the system.
julia> asset_types = MacroEnergy.get_asset_types(system);ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> unique(asset_types)ERROR: UndefVarError: `asset_types` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
asset_ids
Retrieves the IDs of all the assets in the system.
julia> ids = MacroEnergy.asset_ids(system)ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
Once you have the IDs, you can retrieve an asset by its ID using the following function:
get_asset_by_id
Retrieves an asset by its ID.
julia> battery_SE = MacroEnergy.get_asset_by_id(system, :battery_SE);ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> thermal_plant_SE = MacroEnergy.get_asset_by_id(system, :SE_natural_gas_fired_combined_cycle_1);ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
The following function can be useful to retrieve a vector of all the assets of a given type.
get_assets_sametype
Returns a vector of assets of a given type.
julia> batteries = MacroEnergy.get_assets_sametype(system, Battery);ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> battery = batteries[1]; # first battery in the listERROR: UndefVarError: `batteries` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> thermal_plants = MacroEnergy.get_assets_sametype(system, ThermalPower{NaturalGas});ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> thermal_plant = thermal_plants[1]; # first thermal power plant in the listERROR: UndefVarError: `thermal_plants` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
Model Generation and Running
generate_model
Uses JuMP to generate the optimization model for the system data.
julia> model = MacroEnergy.generate_model(system);ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
set_optimizer
Sets the optimizer for the JuMP model.
julia> MacroEnergy.set_optimizer(model, HiGHS.Optimizer);ERROR: UndefVarError: `model` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
optimize!
Solves the optimization model.
julia> MacroEnergy.optimize!(model)ERROR: UndefVarError: `model` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
The following set of functions can be used to retrieve the optimal values of some variables in the model.
get_optimal_capacity
Fetches the final capacities for all assets.
julia> capacity = MacroEnergy.get_optimal_capacity(system);ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> capacity[!, [:commodity, :resource_id, :value]]ERROR: UndefVarError: `capacity` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned. Hint: a global variable of this name also exists in DataStructures.
get_optimal_new_capacity
Fetches the new capacities for all assets.
julia> new_capacity = MacroEnergy.get_optimal_new_capacity(system);ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> new_capacity[!, [:commodity, :resource_id, :value]]ERROR: UndefVarError: `new_capacity` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
get_optimal_retired_capacity
Fetches the retired capacities for all assets.
julia> retired_capacity = MacroEnergy.get_optimal_retired_capacity(system);ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> retired_capacity[!, [:commodity, :resource_id, :value]]ERROR: UndefVarError: `retired_capacity` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
get_optimal_discounted_costs
Fetches all the system costs.
julia> costs = MacroEnergy.get_optimal_discounted_costs(model);ERROR: UndefVarError: `model` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> costs[!, [:variable, :value]]ERROR: UndefVarError: `costs` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
Working with Nodes in a System
Once a System object is loaded, and the model is generated, users can use the following functions to inspect the nodes in the system.
For a comprehensive list of function interfaces available for node besides id, commodity_type and the ones listed below, users can refer to the node.jl and the vertex.jl source code.
find_node
Finds a node in the System by its ID.
julia> elec_node = MacroEnergy.find_node(system.locations, :elec_SE);ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
Nodes, as explained in the Macro Internal Components section, are a unique type of vertex that represent the demand or supply of a commodity, where each vertex in Macro is associated with a balance equation. To programmatically access all balance equations within the system, the following functions are available:
balance_ids: Retrieve the IDs of all balance equations associated with a vertex.get_balance: Obtain the mathematical expression of a specific balance equation.balance_data: Access the input balance data, which typically includes the stoichiometric coefficients of a specific balance equation, if applicable.
Here is an example of how to use these functions to access the balance equations for the electricity node in the system:
balance_ids
Retrieves the IDs of all balance equations in a node.
julia> MacroEnergy.balance_ids(elec_node)ERROR: UndefVarError: `elec_node` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
Macro automatically creates a :demand balance equation for each node that has a BalanceConstraint.
get_balance
Retrieves the mathematical expression of the demand balance equation for the node.
julia> demand_expression = MacroEnergy.get_balance(elec_node, :demand);ERROR: UndefVarError: `elec_node` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> demand_expression[1] # first time stepERROR: UndefVarError: `demand_expression` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
balance_ids
julia> co2_node = MacroEnergy.find_node(system.locations, :co2_sink);ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.balance_ids(co2_node)ERROR: UndefVarError: `co2_node` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
Macro automatically creates an :emissions balance equation for each CO₂ node that has a CO2CapConstraint.
get_balance
julia> emissions_expression = MacroEnergy.get_balance(co2_node, :emissions);ERROR: UndefVarError: `co2_node` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> emissions_expression[1] # first time stepERROR: UndefVarError: `emissions_expression` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
To calculate the total emissions at a node, users should perform the following steps:
julia> emissions_expression = MacroEnergy.get_balance(co2_node, :emissions);ERROR: UndefVarError: `co2_node` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.value(sum(emissions_expression))ERROR: UndefVarError: `emissions_expression` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
To check and visualize the mathematical expressions of the constraints applied to a node, the following functions are available:
all_constraints: Retrieve all constraints associated with a node.all_constraints_types: Retrieve all types of constraints associated with a node.get_constraint_by_type: Retrieve a specific constraint on a node by its type.
all_constraints
Retrieves all the constraints attached to a node.
julia> all_constraints = MacroEnergy.all_constraints(elec_node);ERROR: UndefVarError: `elec_node` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
all_constraints_types
Retrieves all the types of constraints attached to a node.
julia> all_constraints_types = MacroEnergy.all_constraints_types(elec_node)ERROR: UndefVarError: `elec_node` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
get_constraint_by_type, constraint_ref
Retrieves a constraint on a node by its type.
julia> balance_constraint = MacroEnergy.get_constraint_by_type(elec_node, BalanceConstraint);ERROR: UndefVarError: `elec_node` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.constraint_ref(balance_constraint);ERROR: UndefVarError: `balance_constraint` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> max_non_served_demand_constraint = MacroEnergy.get_constraint_by_type(elec_node, MaxNonServedDemandConstraint);ERROR: UndefVarError: `elec_node` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.constraint_ref(max_non_served_demand_constraint)[1:5]ERROR: UndefVarError: `max_non_served_demand_constraint` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
Working with Assets
Together with Locations, assets form the core components of an energy system in Macro. The functions below are essential for managing and interacting with assets.
id
Retrieves the ID of an asset.
julia> thermal_plant = MacroEnergy.get_asset_by_id(system, :SE_natural_gas_fired_combined_cycle_1);ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.id(thermal_plant)ERROR: UndefVarError: `thermal_plant` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
print_struct_info
Prints the structure of an asset in terms of its components (edges, transformations, storages, etc.)
julia> MacroEnergy.print_struct_info(thermal_plant)ERROR: UndefVarError: `thermal_plant` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
Once you have collected the names of the components of an asset, you can use the following function to get a specific component by its name.
get_component_by_fieldname
Retrieves a component of an asset by its field name.
julia> elec_edge = MacroEnergy.get_component_by_fieldname(thermal_plant, :elec_edge);ERROR: UndefVarError: `thermal_plant` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.id(elec_edge)ERROR: UndefVarError: `elec_edge` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.typeof(elec_edge)ERROR: UndefVarError: `elec_edge` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.commodity_type(elec_edge)ERROR: UndefVarError: `elec_edge` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
Alternatively, users can retrieve a specific component using its ID.
get_component_ids
Retrieves the IDs of all the components of an asset.
julia> MacroEnergy.get_component_ids(thermal_plant)ERROR: UndefVarError: `thermal_plant` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
get_component_by_id
Retrieves a component of an asset by its ID.
julia> elec_edge = MacroEnergy.get_component_by_id(thermal_plant, :SE_natural_gas_fired_combined_cycle_1_elec_edge);ERROR: UndefVarError: `thermal_plant` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.id(elec_edge)ERROR: UndefVarError: `elec_edge` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.typeof(elec_edge)ERROR: UndefVarError: `elec_edge` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
Working with Edges
id
Retrieves the ID of an edge.
julia> MacroEnergy.id(elec_edge)ERROR: UndefVarError: `elec_edge` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
commodity_type
Retrieves the commodity type of an edge.
julia> MacroEnergy.commodity_type(elec_edge)ERROR: UndefVarError: `elec_edge` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
For a comprehensive list of function interfaces available for edge besides id, commodity_type and the ones listed below, users can refer to the edge.jl source code.
get_edges
Retrieves all the edges in the system.
julia> edges = MacroEnergy.get_edges(system);ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
capacity
Retrieves the capacity expression of an edge.
julia> capacity_expression = MacroEnergy.capacity(elec_edge)ERROR: UndefVarError: `elec_edge` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
final_capacity
Retrieves the final capacity of an edge (i.e. the optimal value of the capacity expression).
julia> capacity_expression = MacroEnergy.capacity(elec_edge)ERROR: UndefVarError: `elec_edge` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.value(capacity_expression)ERROR: UndefVarError: `capacity_expression` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
flow
Retrieves the flow variables of an edge.
julia> flow_variables = MacroEnergy.flow(elec_edge);ERROR: UndefVarError: `elec_edge` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> flow_variables[1:5]ERROR: UndefVarError: `flow_variables` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
value
Retrieves the values of the flow variables of an edge.
julia> flow_values = MacroEnergy.value.(flow_variables);ERROR: UndefVarError: `flow_variables` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> flow_values[1:5]ERROR: UndefVarError: `flow_values` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
Note that the value function is called with the dot notation to apply it to each element of the flow_variables array (see Julia's documentation for more information).
In this example, we first get the flow of the CO₂ edge and then we call the value function to get the values of these variables.
julia> co2_edge = MacroEnergy.get_component_by_fieldname(thermal_plant, :co2_edge);ERROR: UndefVarError: `thermal_plant` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> emission = MacroEnergy.flow(co2_edge)[1:5]ERROR: UndefVarError: `co2_edge` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> emission_values = MacroEnergy.value.(emission);ERROR: UndefVarError: `emission` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> emission_values[1:5]ERROR: UndefVarError: `emission_values` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
The functions available for nodes when dealing with constraints can also be used for edges.
all_constraints_types
julia> MacroEnergy.all_constraints_types(elec_edge)ERROR: UndefVarError: `elec_edge` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
get_constraint_by_type
julia> constraint = MacroEnergy.get_constraint_by_type(elec_edge, CapacityConstraint);ERROR: UndefVarError: `elec_edge` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.constraint_ref(constraint)[1:5]ERROR: UndefVarError: `constraint` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
start_vertex
Retrieves the starting node of an edge.
julia> start_node = MacroEnergy.start_vertex(elec_edge);ERROR: UndefVarError: `elec_edge` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.id(start_node)ERROR: UndefVarError: `start_node` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.typeof(start_node)ERROR: UndefVarError: `start_node` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
end_vertex
Retrieves the ending node of an edge.
julia> end_node = MacroEnergy.end_vertex(elec_edge);ERROR: UndefVarError: `elec_edge` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.id(end_node)ERROR: UndefVarError: `end_node` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.typeof(end_node)ERROR: UndefVarError: `end_node` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
Working with Transformations
For a comprehensive list of function interfaces available for transformation besides id, commodity_type and the ones listed below, users can refer to the transformation.jl and the vertex.jl source code.
To access the transformation component of an asset, utilize the following functions:
julia> MacroEnergy.print_struct_info(thermal_plant)ERROR: UndefVarError: `thermal_plant` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> thermal_transform = MacroEnergy.get_component_by_fieldname(thermal_plant, :thermal_transform);ERROR: UndefVarError: `thermal_plant` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.id(thermal_transform)ERROR: UndefVarError: `thermal_transform` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.typeof(thermal_transform)ERROR: UndefVarError: `thermal_transform` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
balance_ids
Retrieves the IDs of all the balance equations in a transformation.
julia> MacroEnergy.balance_ids(thermal_transform)ERROR: UndefVarError: `thermal_transform` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
balance_data
Retrieves the balance data of a transformation. This is very useful to check the stoichiometric coefficients of a transformation.
julia> MacroEnergy.balance_data(thermal_transform, :energy)ERROR: UndefVarError: `thermal_transform` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
get_balance
Retrieves the mathematical expression of the balance of a transformation.
julia> MacroEnergy.get_balance(thermal_transform, :energy)[1:5]ERROR: UndefVarError: `thermal_transform` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
We can do the same for the emissions balance equation.
balance_data
julia> MacroEnergy.balance_data(thermal_transform, :emissions)ERROR: UndefVarError: `thermal_transform` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
get_balance
julia> MacroEnergy.get_balance(thermal_transform, :emissions)[1:5]ERROR: UndefVarError: `thermal_transform` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
The functions available for nodes and edges can also be applied to transformations.
all_constraints
julia> MacroEnergy.all_constraints(thermal_transform)ERROR: UndefVarError: `thermal_transform` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
all_constraints_types
julia> MacroEnergy.all_constraints_types(thermal_transform)ERROR: UndefVarError: `thermal_transform` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
get_constraint_by_type
julia> MacroEnergy.get_constraint_by_type(thermal_transform, BalanceConstraint)ERROR: UndefVarError: `thermal_transform` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
Working with Storages
For a comprehensive list of function interfaces available for storage besides id, commodity_type and the ones listed below, users can refer to the storage.jl and the vertex.jl source code.
To access the storage component of an asset, utilize the following functions:
julia> battery = MacroEnergy.get_asset_by_id(system, :battery_SE);ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.print_struct_info(battery)ERROR: UndefVarError: `battery` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> storage = MacroEnergy.get_component_by_fieldname(battery, :battery_storage);ERROR: UndefVarError: `battery` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.id(storage)ERROR: UndefVarError: `storage` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.typeof(storage)ERROR: UndefVarError: `storage` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
balance_ids
Retrieves the IDs of all the balance equations in a storage.
julia> MacroEnergy.balance_ids(storage)ERROR: UndefVarError: `storage` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
balance_data
Retrieves the balance data of a storage. This is very useful to check the stoichiometric coefficients of a storage.
julia> MacroEnergy.balance_data(storage, :storage)ERROR: UndefVarError: `storage` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
get_balance
Retrieves the mathematical expression of the balance of a storage.
julia> MacroEnergy.get_balance(storage, :storage)[1:5]ERROR: UndefVarError: `storage` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
The same set of functions that we have seen for nodes, edges, and transformations are also available for storages.
all_constraints_types
julia> MacroEnergy.all_constraints_types(storage)ERROR: UndefVarError: `storage` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
get_constraint_by_type
julia> MacroEnergy.get_constraint_by_type(storage, BalanceConstraint)ERROR: UndefVarError: `storage` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> constraint = MacroEnergy.get_constraint_by_type(storage, StorageCapacityConstraint);ERROR: UndefVarError: `storage` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.constraint_ref(constraint)[1:5]ERROR: UndefVarError: `constraint` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
storage_level
Retrieves the storage level variables of a storage component.
julia> storage_level = MacroEnergy.storage_level(storage);ERROR: UndefVarError: `storage` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.value.(storage_level)[1:5]ERROR: UndefVarError: `storage_level` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
charge_edge
Retrieves the charge edge connected to a storage component.
julia> charge_edge = MacroEnergy.charge_edge(storage);ERROR: UndefVarError: `storage` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.id(charge_edge)ERROR: UndefVarError: `charge_edge` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.typeof(charge_edge)ERROR: UndefVarError: `charge_edge` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
discharge_edge
Retrieves the discharge edge connected to a storage component.
julia> discharge_edge = MacroEnergy.discharge_edge(storage);ERROR: UndefVarError: `storage` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.id(discharge_edge)ERROR: UndefVarError: `discharge_edge` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.typeof(discharge_edge)ERROR: UndefVarError: `discharge_edge` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
spillage_edge
Retrieves the spillage edge connected to a storage component (applicable to hydro reservoirs).
julia> MacroEnergy.spillage_edge(storage)Time Management
julia> vertex = MacroEnergy.find_node(system.locations, :elec_SE);ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> edge = MacroEnergy.get_component_by_fieldname(thermal_plant, :elec_edge);ERROR: UndefVarError: `thermal_plant` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
time_interval
Retrieves the time interval of a vertex/edge.
julia> MacroEnergy.time_interval(vertex)ERROR: UndefVarError: `vertex` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> MacroEnergy.time_interval(edge)ERROR: UndefVarError: `edge` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
period_map
Retrieves the period map of a vertex/edge.
julia> MacroEnergy.period_map(vertex)ERROR: UndefVarError: `period_map` not defined in `MacroEnergy` Suggestion: check for spelling errors or missing imports.
modeled_subperiods
Retrieves the modeled subperiods of a vertex/edge.
julia> MacroEnergy.modeled_subperiods(vertex)ERROR: UndefVarError: `vertex` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
current_subperiod
Retrieves the subperiod a given time step belongs to for the time series attached to a given vertex/edge.
julia> MacroEnergy.current_subperiod(vertex, 7)ERROR: UndefVarError: `vertex` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
subperiods
Retrieves the subperiods of the time series attached to a vertex/edge.
julia> MacroEnergy.subperiods(vertex)ERROR: UndefVarError: `vertex` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
subperiod_indices
Retrieves the indices of the subperiods of the time series attached to a vertex/edge.
julia> MacroEnergy.subperiod_indices(vertex)ERROR: UndefVarError: `vertex` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
get_subperiod
Retrieves the subperiod of a vertex/edge for a given index.
julia> MacroEnergy.get_subperiod(vertex, 6)ERROR: UndefVarError: `vertex` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
subperiod_weight
Retrieves the weight of a subperiod of a vertex/edge for a given index.
julia> MacroEnergy.subperiod_weight(vertex, 17)ERROR: UndefVarError: `vertex` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
Results Collection
collect_results
Collects all the results from the model as a set of DataFrames:
- All the capacity variables/expressions (capacity, new_capacity, retired_capacity)
- All the flow variables (flow)
- Non-served demand variables (non_served_demand)
- Storage level variables (storage_level)
- Costs (costs)
julia> results = MacroEnergy.collect_results(system, model);ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> first(results, 5)ERROR: UndefVarError: `results` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
reshape_wide
Reshapes the results to wide format.
julia> capacity_results = MacroEnergy.get_optimal_capacity(system; scaling=1e3);ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> new_capacity_results = MacroEnergy.get_optimal_new_capacity(system; scaling=1e3);ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> retired_capacity_results = MacroEnergy.get_optimal_retired_capacity(system; scaling=1e3);ERROR: UndefVarError: `system` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> all_capacity_results = vcat(capacity_results, new_capacity_results, retired_capacity_results);ERROR: UndefVarError: `capacity_results` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> df_wide = MacroEnergy.reshape_wide(all_capacity_results);ERROR: UndefVarError: `all_capacity_results` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.julia> df_wide[1:5, [:commodity, :resource_id, :capacity, :new_capacity, :retired_capacity]]ERROR: UndefVarError: `df_wide` not defined in `Main` Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
write_flow
Writes the flow results to a (CSV, CSV.GZ, or Parquet) file. An optional commodity and asset type filter can be applied.
julia> write_flow("flow.csv", system)
# Filter by commodity: write only the flow of edges of commodity "Electricity"
julia> write_flow("flow.csv", system, commodity="Electricity")
# Filter by commodity and asset type using parameter-free matching
julia> write_flow("flow.csv", system, commodity="Electricity", asset_type="ThermalPower")
# Filter by commodity and asset type using wildcard matching
julia> write_flow("flow.csv", system, commodity="Electricity", asset_type="ThermalPower*")write_capacity
Writes the capacity results to a (CSV, CSV.GZ, or Parquet) file. An optional commodity and asset type filter can be applied.
julia> write_capacity("capacity.csv", system)
# Filter by commodity: write only the capacity of edges of commodity "Electricity"
julia> write_capacity("capacity.csv", system, commodity="Electricity")
# Filter by commodity and asset type using parameter-free matching
julia> write_capacity("capacity.csv", system, asset_type="ThermalPower")
# Filter by asset type using wildcard matching
julia> write_capacity("capacity.csv", system, asset_type="ThermalPower*")
# Filter by commodity and asset type
julia> write_capacity("capacity.csv", system, commodity="Electricity", asset_type=["ThermalPower", "Battery"])write_costs
Writes the costs results to a (CSV, CSV.GZ, or Parquet) file. An optional type filter can be applied.
julia> write_costs("costs.csv", system, model)write_settings
julia> write_settings(case, "settings.json")This function exports case and system settings to a JSON file, useful for debugging and documentation.
write_results
julia> write_results(file_path, system, model, settings, ext=".csv.gz")
julia> write_results(file_path, system, model, settings, ext=".parquet")This function creates multiple output files, one for each result type:
file_path_capacity.ext- Capacity resultsfile_path_flow.ext- Flow resultsfile_path_non_served_demand.ext- Non-served demandfile_path_storage_level.ext- Storage levelsfile_path_discounted_costs.ext- Discounted costsfile_path_undiscounted_costs.ext- Undiscounted costs